package com.heima.wemedia.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Strings;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.minio.MinIOFileOptions;
import com.heima.common.tess4j.Tess4jClient;
import com.heima.feign.clients.ArticleClient;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.service.WmGreenScan;
import com.heima.wemedia.service.WmNewsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.util.*;

@Service
public class WmGreenScanImpl implements WmGreenScan {
    @Autowired
    WmNewsService wmNewsService;
    @Autowired
    MinIOFileOptions minIOFileOptions;
    @Autowired
    GreenTextScan greenTextScan;
    @Autowired
    GreenImageScan greenImageScan;
    @Autowired
    Tess4jClient tess4jClient;
    //TODO:文章审核
    @Override
    @Async//异步调用
//    @GlobalTransactional//seata集成【微服务保护】
    public void greenScanContextImg(Long id) throws Exception {
        Set<String> result=new HashSet<>();//定义集合存储审核结果
        // 1 根据id获取文章
        WmNews wmNews = wmNewsService.getById(id);
        // 2 文本内容、图片
        Map<String, Object> map = parseContextImg(wmNews);
        String context = map.get("content").toString();//文本
        Set<String> images = (Set<String>) map.get("image");//图片
        // 3 站内审核-敏感词过滤（DFA算法+Tess图文识字）
        /*
        【1】 文字=content+图片识字
        【2】 构建敏感词集合
        【3】 检测敏感词
        【4】 检测通过再去调用aliyun，检测不通过直接返回不通过
         */
        // 3.1 站内 文本敏感词检测
        Map<String, Integer> matchWords = SensitiveWordUtil.matchWords(context);
        System.out.println("matchWords = " + matchWords);
        // 3.2 站内 图片敏感词检测
        //下载图片
        List<byte[]> imgs = new ArrayList<>();
        StringBuffer buffer=new StringBuffer();
        for (String image : images) {
            byte[] bytes =minIOFileOptions.downLoadFile(image);
            imgs.add( bytes );//aliyun 二进制文件检测
            //解析每个图片，获取每个图片的文本内容，并拼接到一个字符串中
            ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
            BufferedImage bufferedImage = ImageIO.read(bis);
            //tess4j提取图片文字->doOCR
            String imageContent = tess4jClient.doOCR(bufferedImage);
            if(!ObjectUtils.isEmpty(imageContent)){
                buffer.append(imageContent);
            }
        }
        //dfa敏感词过滤
        if (!ObjectUtils.isEmpty(buffer)) {
            Map<String, Integer> words = SensitiveWordUtil.matchWords(buffer.toString());
            System.out.println("words = " + words);
        }
        // 3.3 审核状态更新
        if (matchWords.size()>0) {
            result.add("block");
            updateArticle(result,wmNews);
            return;
        }
        System.out.println("===================站内审核通过，调用aliyun======================");
        // 4 aliyun第三方接口
        // 4.1 审核文本
        result = greenTextScan.verify(context);
        // 4.2 审核图片
        if (images.size() > 0) {
            //先从MinIO下载
            for (String imageUrl : images) {
                byte[] bytes = minIOFileOptions.downLoadFile(imageUrl);
                imgs.add(bytes);
            }
            //再交给aliyun审核
            result.addAll(greenImageScan.verify(imgs));

        }
        // 4.3 审核状态更新
        updateArticle(result,wmNews);
        if (wmNews.getStatus()==9) {
            //注意：在同步之后，更新文章id
            Long articleId = syncArticle(wmNews);
            wmNews.setArticleId(articleId);//内部远程调用，同步article
//            int i=10/0;
            wmNewsService.updateById(wmNews);
        }
    }


    @Autowired
    WmChannelMapper wmChannelMapper;

    @Autowired
    ArticleClient articleClient;
    //数据同步
    public Long syncArticle(WmNews wmNews) throws Exception {
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);//部分数据无法覆盖，需要完善
        //注意：在同步之前，完善articleDto的数据
        LambdaQueryWrapper<WmChannel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WmChannel::getId,wmNews.getChannelId());
        WmChannel wmChannel = wmChannelMapper.selectOne(wrapper);
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setId(wmNews.getArticleId());
        //调用feign接口
        ResponseResult<Long> result = articleClient.saveArticle(articleDto);
        return result.getData();
    }

    // 提取文章中的文本、图片
    /*
    文本=标题+标签+正文
    图片=封面+正文
     */
    public Map<String, Object> parseContextImg(WmNews wmNews) {
        // 1 定义两个对象存储文本和图片
        StringBuffer content = new StringBuffer();
        Set<String> image = new HashSet<String>();
        // 2 文本提取：标题+标签
        content.append(wmNews.getTitle() + ",").append(wmNews.getLabels() + ",");
        // 3 正文提取(Json字符串)：文本+图片
        List<Map> maps = JSON.parseArray(wmNews.getContent(), Map.class);
        for (Map map : maps) {
            String type = (String) map.get("type");
            String value = (String) map.get("value");
            if (type.equals("text")) {
                content.append(value).append(",");
            } else {
                image.add(value);
            }
        }
        // 4 图片提取：封面
        String images = wmNews.getImages();
        if (!Strings.isNullOrEmpty(images)) {
            // 多张封面，逗号分割
            String[] strings = images.split(",");
            // 数组转成list-》图片集合image
            image.addAll(Arrays.asList(strings));
        }
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("content", content);
        resultMap.put("image", image);
        return resultMap;
    }

    //文章发布/修改-》根据审核结果，处理文章状态
    /*
    文章状态字段：status
        0 草稿
        1 提交（待审恶）
        2 审核失败
        3 人工审核
        4 人工审核通过
        8 审核通过（待发布）
        9 已发布
     */
    void updateArticle(Set<String> result,WmNews wmNews) {
        int status=9;//默认发布
        // 1 审核未通过-》不通过、人工审核
        for (String s : result) {
            if (s.equals("block")) {
                status=2;//审核不通过
                break;
            }
            if (s.equals("review")) {
                status=3;//人工审核
            }
        }
        // 2 发布时间(xxtime.getTime())>当前时间(System.currentTimeMillis())->待发布
        if (wmNews.getPublishTime().getTime()>System.currentTimeMillis()) {
            status=8;
        }
        wmNews.setStatus(status);
        wmNewsService.updateById(wmNews);
    }
}
